package com.ruoyi.slope.data.crack.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.slope.data.crack.domain.SlopeCrackAccStatistic;
import com.ruoyi.slope.data.crack.domain.SlopeCrackChangeStatistic;
import com.ruoyi.slope.data.crack.domain.SlopeCrackData;
import com.ruoyi.slope.data.crack.domain.SlopeCrackTiltAngleStatistic;
import com.ruoyi.slope.data.crack.service.ISlopeCrackDataService;
import com.ruoyi.slope.dataFile.domain.SlopeDataFile;
import com.ruoyi.slope.dataFile.service.ISlopeDataFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 边坡裂缝传感器监测数据Controller
 * 
 * @author psy
 * @date 2025-05-02
 */
@RestController
@RequestMapping("/data/crack")
public class SlopeCrackDataController extends BaseController
{    
    @Autowired
    private ISlopeDataFileService slopeDataFileService;
    @Autowired
    private ISlopeCrackDataService slopeCrackDataService;

    /**
     * 查询边坡裂缝传感器监测数据列表
     */
    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @GetMapping("/list")
    public TableDataInfo list(SlopeCrackData slopeCrackData)
    {
        startPage();
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeCrackDataList(slopeCrackData);
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @GetMapping("/list_qingxie")
    public TableDataInfo listQ(SlopeCrackData slopeCrackData){
        startPage();
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeQingXieDataList(slopeCrackData);
        return getDataTable(list);
    }


    /**
     * 导出边坡裂缝传感器监测数据列表
     */
    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @Log(title = "边坡裂缝传感器监测数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SlopeCrackData slopeCrackData)
    {
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeCrackDataList(slopeCrackData);
        ExcelUtil<SlopeCrackData> util = new ExcelUtil<SlopeCrackData>(SlopeCrackData.class);
        String path = util.exportExcel(response, list, "边坡裂缝传感器监测数据数据");
        SlopeDataFile slopeDataFile = new SlopeDataFile();
        slopeDataFile.setFileName(path);
        slopeDataFileService.insertSlopeDataFile(slopeDataFile);
    }

    /**
     * 导出边坡裂缝传感器监测裂缝变化数据统计列表
     */
    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @Log(title = "边坡裂缝传感器监测数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export/crackChange")
    public void exportCrackChange(HttpServletResponse response, SlopeCrackData slopeCrackData) {
        // 获取数据列表
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeCrackDataList(slopeCrackData);

        // 计算统计数据
        double average = list.stream().mapToDouble(SlopeCrackData::getCrackChange).average().orElse(0);
        double max = list.stream().mapToDouble(SlopeCrackData::getCrackChange).max().orElse(0);
        double rms = Math.sqrt(list.stream().mapToDouble(data -> Math.pow(data.getCrackChange(), 2)).average().orElse(0));

        // 创建一个新的列表，把统计数据加到列表顶部
        List<SlopeCrackChangeStatistic> dataWithStatistics = new ArrayList<>();

        // 可以创建一个虚拟的数据对象用来承载统计数据
        SlopeCrackChangeStatistic statisticsData = new SlopeCrackChangeStatistic();
        statisticsData.setAverageCrackChange(average);
        statisticsData.setAbsoluteMaxCrackChange(max);
        statisticsData.setRootMeanSquareCrackChange(rms);
        dataWithStatistics.add(statisticsData);  // 添加统计数据到列表


        for(SlopeCrackData data : list){
            SlopeCrackChangeStatistic statistics = new SlopeCrackChangeStatistic();
            statistics.setCrackChange(data.getCrackChange());
            statistics.setUpdateTime(data.getUpdateTime());
            statistics.setDeviceSn(data.getDeviceSn());
            statistics.setCrackChangeRate(data.getCrackChangeRate());
            dataWithStatistics.add(statistics);
        }

        // 生成 Excel
        ExcelUtil<SlopeCrackChangeStatistic> util = new ExcelUtil<>(SlopeCrackChangeStatistic.class);

        // 导出带统计数据的 Excel 文件
        String path = util.exportExcel(response, dataWithStatistics, "边坡裂缝传感器监测数据数据"); 
        SlopeDataFile slopeDataFile = new SlopeDataFile();
        slopeDataFile.setFileName(path);
        slopeDataFileService.insertSlopeDataFile(slopeDataFile);
    }

    /**
     * 导出边坡裂缝传感器监测倾斜角度数据统计列表
     */
    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @Log(title = "边坡裂缝传感器监测数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export/crackTiltAngle")
    public void exportCrackTiltAngle(HttpServletResponse response, SlopeCrackData slopeCrackData) {
        // 获取数据列表
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeCrackDataList(slopeCrackData);

        // 计算统计数据
        double average = list.stream().mapToDouble(SlopeCrackData::getXyTiltAngle).average().orElse(0);
        double max = list.stream().mapToDouble(SlopeCrackData::getXyTiltAngle).max().orElse(0);
        double rms = Math.sqrt(list.stream().mapToDouble(data -> Math.pow(data.getXyTiltAngle(), 2)).average().orElse(0));

        // 创建一个新的列表，把统计数据加到列表顶部
        List<SlopeCrackTiltAngleStatistic> dataWithStatistics = new ArrayList<>();

        // 可以创建一个虚拟的数据对象用来承载统计数据
        SlopeCrackTiltAngleStatistic statisticsData = new SlopeCrackTiltAngleStatistic();
        statisticsData.setAverageXYTiltAngle(average);
        statisticsData.setAbsoluteMaxXYTiltAngle(max);
        statisticsData.setRootMeanSquareXYTiltAngle(rms);
        dataWithStatistics.add(statisticsData);  // 添加统计数据到列表


        for(SlopeCrackData data : list){
            SlopeCrackTiltAngleStatistic statistics = new SlopeCrackTiltAngleStatistic();
            statistics.setXTiltAngle(data.getXTiltAngle());
            statistics.setYTiltAngle(data.getYTiltAngle());
            statistics.setZTiltAngle(data.getZTiltAngle());
            statistics.setXyTiltAngle(data.getXyTiltAngle());
            statistics.setXTiltAngleChangeRate(data.getXTiltAngleChangeRate());
            statistics.setYTiltAngleChangeRate(data.getYTiltAngleChangeRate());
            statistics.setZTiltAngleChangeRate(data.getZTiltAngleChangeRate());
            statistics.setXyTiltAngleChangeRate(data.getXyTiltAngleChangeRate());
            statistics.setAzimuth(data.getAzimuth());
            statistics.setUpdateTime(data.getUpdateTime());
            statistics.setDeviceSn(data.getDeviceSn());
            dataWithStatistics.add(statistics);
        }

        // 生成 Excel
        ExcelUtil<SlopeCrackTiltAngleStatistic> util = new ExcelUtil<>(SlopeCrackTiltAngleStatistic.class);

        // 导出带统计数据的 Excel 文件
        String path = util.exportExcel(response, dataWithStatistics, "边坡裂缝传感器监测数据数据"); 
        SlopeDataFile slopeDataFile = new SlopeDataFile();
        slopeDataFile.setFileName(path);
        slopeDataFileService.insertSlopeDataFile(slopeDataFile);
    }

    /**
     * 导出边坡裂缝传感器监测倾斜角度数据统计列表
     */
    @PreAuthorize("@ss.hasPermi('deviceInfo:deviceInfo:list')")
    @Log(title = "边坡裂缝传感器监测数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export/crackXAcc")
    public void exportCrackXAcc(HttpServletResponse response, SlopeCrackData slopeCrackData) {
        // 获取数据列表
        List<SlopeCrackData> list = slopeCrackDataService.selectSlopeCrackDataList(slopeCrackData);

        // 计算统计数据
        double xAverage = list.stream().mapToDouble(SlopeCrackData::getXAcceleration).average().orElse(0);
        double xMax = list.stream().mapToDouble(SlopeCrackData::getXAcceleration).max().orElse(0);
        double xRms = Math.sqrt(list.stream().mapToDouble(data -> Math.pow(data.getXAcceleration(), 2)).average().orElse(0));

        // 计算统计数据
        double yAverage = list.stream().mapToDouble(SlopeCrackData::getYAcceleration).average().orElse(0);
        double yMax = list.stream().mapToDouble(SlopeCrackData::getYAcceleration).max().orElse(0);
        double yRms = Math.sqrt(list.stream().mapToDouble(data -> Math.pow(data.getYAcceleration(), 2)).average().orElse(0));

        // 计算统计数据
        double zAverage = list.stream().mapToDouble(SlopeCrackData::getZAcceleration).average().orElse(0);
        double zMax = list.stream().mapToDouble(SlopeCrackData::getZAcceleration).max().orElse(0);
        double zRms = Math.sqrt(list.stream().mapToDouble(data -> Math.pow(data.getZAcceleration(), 2)).average().orElse(0));

        // 创建一个新的列表，把统计数据加到列表顶部
        List<SlopeCrackAccStatistic> dataWithStatistics = new ArrayList<>();

        // 可以创建一个虚拟的数据对象用来承载统计数据
        SlopeCrackAccStatistic statisticsData = new SlopeCrackAccStatistic();
        statisticsData.setAverageXAcc(xAverage);
        statisticsData.setAbsoluteMaxXAcc(xMax);
        statisticsData.setRootMeanSquareXAcc(xRms);
        statisticsData.setAverageYAcc(yAverage);
        statisticsData.setAbsoluteMaxYAcc(yMax);
        statisticsData.setRootMeanSquareYAcc(yRms);
        statisticsData.setAverageZAcc(zAverage);
        statisticsData.setAbsoluteMaxZAcc(zMax);
        statisticsData.setRootMeanSquareZAcc(zRms);
        dataWithStatistics.add(statisticsData);  // 添加统计数据到列表


        for(SlopeCrackData data : list){
            SlopeCrackAccStatistic statistics = new SlopeCrackAccStatistic();
            statistics.setXAcceleration(data.getXTiltAngle());
            statistics.setYAcceleration(data.getYTiltAngle());
            statistics.setZAcceleration(data.getZTiltAngle());
            statistics.setUpdateTime(data.getUpdateTime());
            statistics.setDeviceSn(data.getDeviceSn());
            dataWithStatistics.add(statistics);
        }

        // 生成 Excel
        ExcelUtil<SlopeCrackAccStatistic> util = new ExcelUtil<>(SlopeCrackAccStatistic.class);

        // 导出带统计数据的 Excel 文件
        String path = util.exportExcel(response, dataWithStatistics, "边坡裂缝传感器监测数据数据"); 
        SlopeDataFile slopeDataFile = new SlopeDataFile();
        slopeDataFile.setFileName(path);
        slopeDataFileService.insertSlopeDataFile(slopeDataFile);
    }
}
